<template>
  <view class="warehouse-selector">
    <view class="picker" @click="showCustomPicker">
      <text class="picker-text">{{ displayText || '请选择仓库/库区/库位' }}</text>
      <uni-icons type="arrowdown" size="16" color="#999"></uni-icons>
    </view>
    
    <!-- 自定义选择器弹窗 -->
    <view class="custom-picker-modal" v-if="showPicker" @click="handleMaskClick">
      <view class="picker-content" @click.stop>
        <view class="picker-header">
          <text class="picker-title">选择仓库</text>
          <uni-icons type="close" size="20" color="#999" @click="hideCustomPicker"></uni-icons>
        </view>
        
        <!-- 扫码输入区域 -->
        <view class="scan-input-section">
          <view class="scan-input-container">
            <input 
              class="scan-input" 
              v-model="scanInputValue"
              placeholder="请输入或扫码库位编码"
              :focus="inputFocusKey > 0"
              @input="handleScanInput"
              @confirm="handleScanConfirm"
              @blur="handleInputBlur"
            />
            <view class="input-actions">
              <view 
                class="clear-btn" 
                v-if="scanInputValue" 
                @click="handleClearInput"
              >
                <uni-icons type="clear" size="16" color="#999"></uni-icons>
              </view>
              <button class="scan-btn" @click="handleScanCode">
                <uni-icons type="scan" size="16" color="#28a745"></uni-icons>
                扫码
              </button>
            </view>
          </view>
          
          <!-- 扫码结果提示 -->
          <view class="scan-result" v-if="scanResult">
            <view class="scan-result-content" :class="{ success: scanResult.success, error: !scanResult.success }">
              <uni-icons :type="scanResult.success ? 'checkmarkempty' : 'closeempty'" size="16" :color="scanResult.success ? '#28a745' : '#dc3545'"></uni-icons>
              <text class="scan-result-text">{{ scanResult.message }}</text>
            </view>
          </view>
        </view>
        
        <view class="picker-body">
          <!-- 步骤指示器 -->
          <view class="step-indicator">
            <view class="step-item" :class="{ active: currentStep >= 0, completed: currentStep > 0 }">
              <text class="step-number">1</text>
              <text class="step-label">仓库</text>
            </view>
            <view class="step-line" :class="{ active: currentStep > 0 }"></view>
            <view class="step-item" :class="{ active: currentStep >= 1, completed: currentStep > 1 }">
              <text class="step-number">2</text>
              <text class="step-label">库区</text>
            </view>
            <view class="step-line" :class="{ active: currentStep > 1 }"></view>
            <view class="step-item" :class="{ active: currentStep >= 2 }">
              <text class="step-number">3</text>
              <text class="step-label">库位</text>
            </view>
          </view>
          
          <!-- 选择内容区域 -->
          <view class="selection-content">
            <!-- 仓库选择 -->
            <view class="selection-step" v-if="currentStep === 0">
              <view class="step-title">请选择仓库</view>
              <scroll-view class="option-list" scroll-y>
                <view 
                  class="option-item" 
                  v-for="(warehouse, index) in rawTree" 
                  :key="warehouse.id"
                  @click="selectWarehouse(index)"
                >
                  <view class="option-content">
                    <text class="option-name">{{ warehouse.name }}</text>
                    <text class="option-code" v-if="warehouse.code">{{ warehouse.code }}</text>
                  </view>
                  <uni-icons type="arrowright" size="16" color="#ccc"></uni-icons>
                </view>
              </scroll-view>
            </view>
            
            <!-- 库区选择 -->
            <view class="selection-step" v-if="currentStep === 1">
              <view class="step-title">请选择库区</view>
              <view class="selected-path">
                <text class="path-text">已选择：{{ selectedWarehouse && selectedWarehouse.name }}</text>
              </view>
              <scroll-view class="option-list" scroll-y>
                <view 
                  class="option-item" 
                  v-for="(location, index) in currentLocations" 
                  :key="location.id"
                  @click="selectLocation(index)"
                >
                  <view class="option-content">
                    <text class="option-name">{{ location.name }}</text>
                    <text class="option-code" v-if="location.code">{{ location.code }}</text>
                  </view>
                  <uni-icons type="arrowright" size="16" color="#ccc"></uni-icons>
                </view>
              </scroll-view>
            </view>
            
            <!-- 库位选择 -->
            <view class="selection-step" v-if="currentStep === 2">
              <view class="step-title">请选择库位</view>
              <view class="selected-path">
                <text class="path-text">已选择：{{ selectedWarehouse && selectedWarehouse.name }} > {{ selectedLocation && selectedLocation.name }}</text>
              </view>
              
              <scroll-view class="option-list" scroll-y>
                <view 
                  class="option-item" 
                  :class="{ 'scan-highlight': scanResult && scanResult.success && scanResult.areaIndex === index }"
                  v-for="(area, index) in currentAreas" 
                  :key="area.id"
                  @click="selectArea(index)"
                >
                  <view class="option-content">
                    <text class="option-name">{{ area.name }}</text>
                    <text class="option-code" v-if="area.code">{{ area.code }}</text>
                  </view>
                  <uni-icons type="checkmarkempty" size="16" color="#28a745" v-if="indexes[2] === index"></uni-icons>
                </view>
              </scroll-view>
            </view>
          </view>
        </view>
        
        <view class="picker-footer">
          <button class="picker-btn cancel-btn" @click="hideCustomPicker">取消</button>
          <button 
            class="picker-btn back-btn" 
            @click="goBackStep" 
            v-if="currentStep > 0"
          >
            上一步
          </button>
          <button 
            class="picker-btn confirm-btn" 
            @click="confirmSelection"
            v-if="currentStep === 2 && indexes[2] >= 0"
          >
            确定
          </button>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import { getTreeList } from '@/api/wm/warehouse.js'

export default {
  name: 'WarehouseSelector',
  props: {
    // 固定的仓库ID（用于收货时限制选择范围）
    warehouseId: {
      type: [String, Number],
      default: null
    },
    // 分别控制三个层级的显示模式
    warehouseDisplayMode: {
      type: String,
      default: 'name' // 'name', 'code', 'both'
    },
    locationDisplayMode: {
      type: String,
      default: 'name' // 'name', 'code', 'both'
    },
    areaDisplayMode: {
      type: String,
      default: 'code' // 'name', 'code', 'both'
    },
    // 是否自动打开选择器（用于嵌入式场景，如弹窗中）
    autoOpen: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      rawTree: [],
      indexes: [0, 0, 0],
      displayText: '',
      showPicker: false,
      currentStep: 0,
      scanResult: null,
      scanInputValue: '',
      inputFocusKey: 0,
      scanInputTimer: null
    }
  },
  computed: {
    // 当前选中的仓库的库区列表
    currentLocations() {
      const warehouse = this.rawTree[this.indexes[0]]
      return warehouse && warehouse.children ? warehouse.children : []
    },
    
    // 当前选中的库区的库位列表
    currentAreas() {
      const location = this.currentLocations[this.indexes[1]]
      return location && location.children ? location.children : []
    },
    
    // 当前选中的仓库
    selectedWarehouse() {
      return this.rawTree[this.indexes[0]] || null
    },
    
    // 当前选中的库区
    selectedLocation() {
      return this.currentLocations[this.indexes[1]] || null
    }
  },
  
  async mounted() {
    await this.loadTreeData()
    // 自动打开模式：数据加载完成后直接打开选择器
    if (this.autoOpen) {
      this.$nextTick(() => {
        this.showPicker = true
      })
    }
  },
  
  watch: {
    // 统一的聚焦控制：选择器打开时聚焦输入框
    showPicker(val) {
      if (val) {
        this.focusInput()
      } else {
        // 关闭时重置焦点 key
        this.inputFocusKey = 0
      }
    }
  },
  
  beforeDestroy() {
    // 清除防抖定时器
    if (this.scanInputTimer) {
      clearTimeout(this.scanInputTimer)
      this.scanInputTimer = null
    }
  },
  
  methods: {
    // 聚焦到输入框
    focusInput() {
      this.$nextTick(() => this.inputFocusKey++)
    },
    
    async loadTreeData() {
      try {
        const res = await getTreeList()        
        if (res.code === 200 && res.data && res.data.length > 0) {
          // 如果有固定的仓库ID，只显示该仓库的数据
          let filteredData = res.data
          if (this.warehouseId) {
            filteredData = res.data.filter(warehouse => 
              (warehouse.warehouseId || warehouse.id) == this.warehouseId
            )
          }
          
          this.rawTree = filteredData.map((warehouse, warehouseIndex) => ({
            id: warehouse.warehouseId || warehouse.id,
            code: warehouse.warehouseCode || warehouse.code,
            name: warehouse.warehouseName || warehouse.name || `仓库${warehouseIndex + 1}`,
            children: (warehouse.children || []).map((location, locationIndex) => ({
              id: location.locationId || location.id,
              code: location.locationCode || location.code,
              name: location.locationName || location.name || `库区${locationIndex + 1}`,
              children: (location.children || []).map((area, areaIndex) => ({
                id: area.areaId || area.id,
                code: area.areaCode || area.code,
                name: area.areaName || area.name || `库位${areaIndex + 1}`
              }))
            }))
          }))
          this.indexes = [0, 0, 0]
        } else {
          uni.showToast({
            title: res.msg || '获取仓库数据失败',
            icon: 'none'
          });
        }
      } catch (error) {
        console.error('加载仓库数据失败:', error)
        uni.showToast({
          title: '加载仓库数据失败',
          icon: 'none'
        });
      }
    },
    
    // 获取显示文本 - 根据层级使用不同的显示模式
    getDisplayText(item, type) {
      if (!item) return '未知'
      
      let displayMode = 'name'
      switch (type) {
        case 'warehouse':
          displayMode = this.warehouseDisplayMode
          break
        case 'location':
          displayMode = this.locationDisplayMode
          break
        case 'area':
          displayMode = this.areaDisplayMode
          break
      }
      
      switch (displayMode) {
        case 'code':
          return item.code || '无编码'
        case 'both':
          return `${item.name || '未知'}(${item.code || '无编码'})`
        case 'name':
        default:
          return item.name || '未知'
      }
    },
    
    // 更新显示文本
    updateDisplayText() {
      const w = this.rawTree[this.indexes[0]]
      const l = w && w.children ? w.children[this.indexes[1]] : null
      const a = l && l.children ? l.children[this.indexes[2]] : null
      
      // 根据显示模式参数生成显示文本
      const warehouseText = w ? this.getDisplayText(w, 'warehouse') : ''
      const locationText = l ? this.getDisplayText(l, 'location') : ''
      const areaText = a ? this.getDisplayText(a, 'area') : ''
      
      this.displayText = [warehouseText, locationText, areaText].filter(Boolean).join(' / ')
    },
    
    // 发送选中事件
    emitSelected() {
      const w = this.rawTree[this.indexes[0]]
      const l = w && w.children ? w.children[this.indexes[1]] : null
      const a = l && l.children ? l.children[this.indexes[2]] : null
      
      // 向父组件传递选中的完整数据
      this.$emit('selected', {
        warehouse: w,
        location: l,
        area: a,
        warehouseId: w && w.id,
        warehouseCode: w && w.code,
        warehouseName: w && w.name,
        locationId: l && l.id,
        locationCode: l && l.code,
        locationName: l && l.name,
        areaId: a && a.id,
        areaCode: a && a.code,
        areaName: a && a.name
      })
    },
    
    // 显示自定义选择器
    showCustomPicker() {
      this.showPicker = true
      this.currentStep = 0
      this.scanResult = null
      this.scanInputValue = ''
    },
    
    // 隐藏自定义选择器
    hideCustomPicker() {
      this.showPicker = false
      this.currentStep = 0
      this.scanResult = null
      this.scanInputValue = ''
      
      if (this.scanInputTimer) {
        clearTimeout(this.scanInputTimer)
        this.scanInputTimer = null
      }
    },
    
    // 处理遮罩点击
    handleMaskClick() {
      this.hideCustomPicker()
    },
    
    // 选择仓库
    selectWarehouse(index) {
      this.indexes[0] = index
      this.indexes[1] = 0
      this.indexes[2] = 0
      
      // 检查是否有库区，如果有则进入下一步
      const warehouse = this.rawTree[index]
      if (warehouse && warehouse.children && warehouse.children.length > 0) {
        this.currentStep = 1
      } else {
        // 没有库区，直接完成选择
        this.currentStep = 2
        this.updateDisplayText()
        this.emitSelected()
      }
    },
    
    // 选择库区
    selectLocation(index) {
      this.indexes[1] = index
      this.indexes[2] = 0
      
      // 检查是否有库位，如果有则进入下一步
      const location = this.currentLocations[index]
      if (location && location.children && location.children.length > 0) {
        this.currentStep = 2
      } else {
        // 没有库位，直接完成选择
        this.updateDisplayText()
        this.emitSelected()
      }
    },
    
    // 选择库位
    selectArea(index) {
      this.indexes[2] = index
      this.updateDisplayText()
      this.emitSelected()
    },
    
    // 返回上一步
    goBackStep() {
      if (this.currentStep > 0) {
        this.currentStep--
      }
    },
    
    // 确认选择
    confirmSelection() {
      this.hideCustomPicker()
    },
    
    // 处理扫码输入框输入
    handleScanInput(e) {
      this.scanInputValue = e.detail.value
      
      // 清除之前的定时器
      if (this.scanInputTimer) {
        clearTimeout(this.scanInputTimer)
      }
      
      // 清除之前的扫码结果提示
      this.scanResult = null
      
      // 防抖处理：输入停止300ms后自动执行查找
      // 这样可以确保PDA扫码时完整获取编码后再执行
      this.scanInputTimer = setTimeout(() => {
        const value = this.scanInputValue.trim()
        if (value) {
          console.log('防抖触发，执行库位查找:', value)
          this.processScanResult(value)
        }
      }, 300)
    },
    
    // 处理扫码输入框确认（手动按回车时）
    handleScanConfirm() {
      // 清除防抖定时器，立即执行
      if (this.scanInputTimer) {
        clearTimeout(this.scanInputTimer)
        this.scanInputTimer = null
      }
      
      if (this.scanInputValue.trim()) {
        this.processScanResult(this.scanInputValue.trim())
      }
    },
    
    // 处理输入框失焦
    handleInputBlur() {
      // 失焦时保留用户输入，以便点击列表选择
    },
    
    // 清除输入框内容
    handleClearInput() {
      this.scanInputValue = ''
      this.scanResult = null
      if (this.scanInputTimer) {
        clearTimeout(this.scanInputTimer)
        this.scanInputTimer = null
      }
      this.focusInput()
    },
    
    // 处理扫码
    async handleScanCode() {
      try {
        // 调用扫码功能
        const result = await this.scanCode()
        if (result) {
          this.scanInputValue = result
          this.processScanResult(result)
        }
      } catch (error) {
        console.error('扫码失败:', error)
        uni.showToast({
          title: '扫码失败，请重试',
          icon: 'none'
        })
      }
    },
    
    // 扫码功能
    scanCode() {
      return new Promise((resolve, reject) => {
        uni.scanCode({
          success: (res) => {
            console.log('扫码结果:', res)
            resolve(res.result)
          },
          fail: (err) => {
            console.error('扫码失败:', err)
            reject(err)
          }
        })
      })
    },
    
    // 处理扫码结果
    processScanResult(scanCode) {
      // 清除之前的扫码结果
      this.scanResult = null
      
      // 直接用编码查找库位
      const matchResult = this.findAreaByCode(scanCode)
      
      if (matchResult.found) {
        // 找到匹配的库位，直接选中
        this.indexes[2] = matchResult.areaIndex
        this.updateDisplayText()
        this.emitSelected()
        
        // 扫码成功不显示提示，只清空输入框
        this.scanInputValue = ''
        
      } else {
        // 未找到匹配的库位，显示错误提示
        this.scanResult = {
          success: false,
          message: matchResult.message,
          scanCode: scanCode
        }
        
        // 5秒后清除错误提示
        setTimeout(() => {
          this.scanResult = null
        }, 5000)
      }
    },
    
    // 根据编码查找库位
    findAreaByCode(areaCode) {
      // 遍历所有仓库、库区、库位，查找匹配的编码
      for (let warehouseIndex = 0; warehouseIndex < this.rawTree.length; warehouseIndex++) {
        const warehouse = this.rawTree[warehouseIndex]
        const locations = warehouse.children || []
        
        for (let locationIndex = 0; locationIndex < locations.length; locationIndex++) {
          const location = locations[locationIndex]
          const areas = location.children || []
          
          for (let areaIndex = 0; areaIndex < areas.length; areaIndex++) {
            const area = areas[areaIndex]
            
            // 检查库位编码是否匹配
            if (area.code === areaCode) {
              // 找到匹配的库位，自动跳转到对应位置
              this.indexes[0] = warehouseIndex
              this.indexes[1] = locationIndex
              this.indexes[2] = areaIndex
              this.currentStep = 2 // 跳转到库位选择步骤
              
              return {
                found: true,
                area: area,
                areaIndex: areaIndex
              }
            }
          }
        }
      }
      
      // 未找到匹配的库位
      return {
        found: false,
        message: `未找到库位编码：${areaCode}`
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.warehouse-selector {
  position: relative;
  
  .picker {
    padding: 20rpx;
    border: 1rpx solid #ddd;
    border-radius: 8rpx;
    background-color: #fff;
    min-height: 60rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
    
    .picker-text {
      font-size: 26rpx;
      color: #333;
      flex: 1;
    }
    
    &:active {
      background-color: #f5f5f5;
    }
  }
  
  .custom-picker-modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10001;
    
    .picker-content {
      width: 90%;
      max-width: 600rpx;
      max-height: 80vh;
      background: #fff;
      border-radius: 16rpx;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      
      .picker-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 30rpx;
        border-bottom: 1rpx solid #eee;
        background: #f8f9fa;
        
        .picker-title {
          font-size: 32rpx;
          font-weight: bold;
          color: #333;
        }
      }
      
      .scan-input-section {
        padding: 20rpx 30rpx;
        border-bottom: 1rpx solid #eee;
        background: #fff;
        
        .scan-input-container {
          display: flex;
          align-items: center;
          gap: 20rpx;
          
          .scan-input {
            flex: 1;
            height: 80rpx;
            padding: 0 20rpx;
            border: 1rpx solid #ddd;
            border-radius: 8rpx;
            font-size: 26rpx;
            background: #f8f9fa;
            
            &:focus {
              background: #fff;
              border-color: #28a745;
            }
          }
          
          .input-actions {
            display: flex;
            align-items: center;
            gap: 12rpx;
            
            .clear-btn {
              display: flex;
              align-items: center;
              justify-content: center;
              width: 60rpx;
              height: 60rpx;
              background: #f5f5f5;
              border-radius: 8rpx;
              cursor: pointer;
              
              &:active {
                background: #e8e8e8;
              }
            }
            
            .scan-btn {
              display: flex;
              align-items: center;
              gap: 8rpx;
              padding: 0 20rpx;
              height: 80rpx;
              background: #f8f9fa;
              border: 1rpx solid #28a745;
              border-radius: 8rpx;
              font-size: 24rpx;
              color: #28a745;
              white-space: nowrap;
              
              &:active {
                background: #e8f5e8;
              }
            }
          }
        }
        
        .scan-result {
          margin-top: 20rpx;
          
          .scan-result-content {
            display: flex;
            align-items: center;
            gap: 12rpx;
            padding: 15rpx 20rpx;
            border-radius: 8rpx;
            
            &.success {
              background: #d4edda;
              border: 1rpx solid #c3e6cb;
              
              .scan-result-text {
                color: #155724;
              }
            }
            
            &.error {
              background: #f8d7da;
              border: 1rpx solid #f5c6cb;
              
              .scan-result-text {
                color: #721c24;
              }
            }
            
            .scan-result-text {
              font-size: 24rpx;
              flex: 1;
            }
          }
        }
      }
      
      .picker-body {
        flex: 1;
        display: flex;
        flex-direction: column;
        padding: 30rpx;
        
        .step-indicator {
          display: flex;
          align-items: center;
          justify-content: center;
          margin-bottom: 40rpx;
          
          .step-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            
            .step-number {
              width: 40rpx;
              height: 40rpx;
              border-radius: 50%;
              background: #f5f5f5;
              color: #999;
              font-size: 24rpx;
              display: flex;
              align-items: center;
              justify-content: center;
              margin-bottom: 8rpx;
            }
            
            .step-label {
              font-size: 22rpx;
              color: #999;
            }
            
            &.active {
              .step-number {
                background: #28a745;
                color: #fff;
              }
              
              .step-label {
                color: #28a745;
                font-weight: bold;
              }
            }
            
            &.completed {
              .step-number {
                background: #20c997;
                color: #fff;
              }
            }
          }
          
          .step-line {
            width: 60rpx;
            height: 2rpx;
            background: #f5f5f5;
            margin: 0 20rpx;
            margin-bottom: 28rpx;
            
            &.active {
              background: #28a745;
            }
          }
        }
        
        .selection-content {
          flex: 1;
          
          .selection-step {
            .step-title {
              font-size: 28rpx;
              font-weight: bold;
              color: #333;
              margin-bottom: 20rpx;
            }
            
            .selected-path {
              background: #f8f9fa;
              padding: 15rpx 20rpx;
              border-radius: 8rpx;
              margin-bottom: 20rpx;
              
              .path-text {
                font-size: 24rpx;
                color: #666;
              }
            }
            
            
            .option-list {
              max-height: 400rpx;
              
              .option-item {
                display: flex;
                align-items: center;
                justify-content: space-between;
                padding: 20rpx;
                border-bottom: 1rpx solid #f0f0f0;
                cursor: pointer;
                transition: all 0.3s ease;
                
                &:active {
                  background-color: #f5f5f5;
                }
                
                &.scan-highlight {
                  background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
                  border: 2rpx solid #28a745;
                  border-radius: 8rpx;
                  margin: 4rpx 0;
                  box-shadow: 0 2rpx 8rpx rgba(40, 167, 69, 0.2);
                }
                
                .option-content {
                  flex: 1;
                  display: flex;
                  flex-direction: column;
                  
                  .option-name {
                    font-size: 26rpx;
                    color: #333;
                    margin-bottom: 4rpx;
                  }
                  
                  .option-code {
                    font-size: 22rpx;
                    color: #999;
                  }
                }
              }
            }
          }
        }
      }
      
      .picker-footer {
        display: flex;
        gap: 20rpx;
        padding: 30rpx;
        border-top: 1rpx solid #eee;
        background: #f8f9fa;
        
        .picker-btn {
          height: 80rpx;
          border-radius: 40rpx;
          border: none;
          font-size: 28rpx;
          font-weight: bold;
          
          &.cancel-btn {
            flex: 1;
            background: #f8f9fa;
            color: #666;
            border: 1rpx solid #ddd;
          }
          
          &.back-btn {
            flex: 1;
            background: #fff;
            color: #666;
            border: 1rpx solid #ddd;
          }
          
          &.confirm-btn {
            flex: 1;
            background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
            color: #fff;
          }
        }
      }
    }
  }
}
</style>
